package com.dc.web.controller;


import com.dc.constant.MessageConstant;
import com.dc.dao.*;
import com.dc.entity.*;
import com.dc.exception.ServiceException;
import com.dc.model.AjaxResult;
import com.dc.model.PageListBody;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Api(tags = "6-涂装清洁超水除锈-2-超水除锈")
@RestController
@RequestMapping("/api/calibration_water_rust_clean")
@Slf4j
public class CalibrationWaterRustCleanController {

    @Resource
    CalibrationWaterRustCleanDao calibrationWaterRustCleanDao;

    @Resource
    CalibrationWaterRustCleanChildDao calibrationWaterRustCleanChildDao;

    @Resource
    ShipDao shipDao;

    @GetMapping("/list")
    public AjaxResult list(PageListBody body) {

        Integer pageNumber = body.getPageNumber();
        pageNumber = ObjectUtils.defaultIfNull(pageNumber, 1);
        Integer pageSize = body.getPageSize();
        pageSize = ObjectUtils.defaultIfNull(pageSize, 20);

        PageRequest pageRequest = PageRequest.of(pageNumber - 1, pageSize);

        Page<CalibrationWaterRustCleanEntity> all = calibrationWaterRustCleanDao.findAll(pageRequest);

        all.getContent().forEach(t-> {
            t.setShipId(t.getShip().getId());
            t.setShipName(t.getShip().getName());
        });

        return AjaxResult.success(all);
    }

    @GetMapping("/{id}")
    public AjaxResult show(@PathVariable("id") Long id) {
        Optional<CalibrationWaterRustCleanEntity> optional = calibrationWaterRustCleanDao.findById(id);
        CalibrationWaterRustCleanEntity entity = null;
        if (optional.isPresent()) {
            entity = optional.get();
            entity.setShipId(entity.getShip().getId());
            entity.setShipName(entity.getShip().getName());
            return AjaxResult.success(entity);
        } else {
            return AjaxResult.error("数据不存在! id = " + id);
        }
    }

    @PostMapping()
    public AjaxResult add(@RequestBody CalibrationWaterRustCleanEntity entity) {
        entity.setId(null);
        Optional<ShipEntity> optionalShip = shipDao.findById(entity.getShipId());
        if(!optionalShip.isPresent()) {
            throw new ServiceException(MessageConstant.ERR_SHIP_MISSING);
        }
        ShipEntity ship = optionalShip.get();
        entity.setShip(ship);
        // 动态计算
        calc(entity);

        CalibrationWaterRustCleanEntity save = calibrationWaterRustCleanDao.save(entity);
        save.setShipName(ship.getName());
        return AjaxResult.success(save);
    }

    @PutMapping("/{id}")
    public AjaxResult update(@PathVariable("id") Long id, @RequestBody CalibrationWaterRustCleanEntity entity) {

        Optional<CalibrationWaterRustCleanEntity> optionalRust = calibrationWaterRustCleanDao.findById(id);
        if(!optionalRust.isPresent()) {
            throw new ServiceException(MessageConstant.ERR_CALIBRATION_MISSION);
        }

        CalibrationWaterRustCleanEntity rustEntity = optionalRust.get();

        if(!rustEntity.getShip().getId().equals(entity.getShipId())) {      // 如果ship有更换，则更新shipId，否则不更新shipID
            Optional<ShipEntity> optionalShip = shipDao.findById(entity.getShipId());
            if(!optionalShip.isPresent()) {
                throw new ServiceException(MessageConstant.ERR_SHIP_MISSING);
            }
            ShipEntity ship = optionalShip.get();
            rustEntity.setShip(ship);
        }

        //////////// 更新字段
        rustEntity.setArea(entity.getArea());
        ///////////

        /////////// 动态更新
        calc(rustEntity);
        //////////

        ShipEntity ship = rustEntity.getShip();

        CalibrationWaterRustCleanEntity save = calibrationWaterRustCleanDao.save(rustEntity);
        save.setShipId(ship.getId());
        save.setShipName(ship.getName());
        save.getInner().forEach(t -> t.setPid(save.getId()));

        return AjaxResult.success(save);
    }

    @DeleteMapping("/{id}")
    public AjaxResult delete(@PathVariable("id") Long id) {
        Optional<CalibrationWaterRustCleanEntity> optional = calibrationWaterRustCleanDao.findById(id);
        if (optional.isPresent()) {
            CalibrationWaterRustCleanEntity entity = optional.get();
            List<CalibrationWaterRustCleanChildEntity> inner = entity.getInner();

            if(ObjectUtils.isNotEmpty(inner)) {
                Collection<Long> collect = inner.stream().map(CalibrationWaterRustCleanChildEntity::getId).collect(Collectors.toList());
                calibrationWaterRustCleanChildDao.deleteAllById(collect);
            }
            calibrationWaterRustCleanDao.deleteById(id);

        }
        return AjaxResult.success();
    }

    /////////////////////////////////////// child ////////////////////////////////////////////

    @GetMapping("/child/{id}")
    public AjaxResult showChild(@PathVariable("id") Long id) {
        Optional<CalibrationWaterRustCleanChildEntity> optional = calibrationWaterRustCleanChildDao.findById(id);
        CalibrationWaterRustCleanChildEntity entity = null;
        if (optional.isPresent()) {
            entity = optional.get();
            entity.setPid(entity.getCalibrationWaterRustCleanEntity().getId());
            return AjaxResult.success(entity);
        } else {
            return AjaxResult.error("数据不存在! id = " + id);
        }
    }

    @PostMapping("/child")
    public AjaxResult addChild(@RequestBody CalibrationWaterRustCleanChildEntity entity) {
        entity.setId(null);
        Optional<CalibrationWaterRustCleanEntity> optional = calibrationWaterRustCleanDao.findById(entity.getPid());

        if(!optional.isPresent()) {
            throw new ServiceException(MessageConstant.ERR_CALIBRATION_MISSION);
        }

        CalibrationWaterRustCleanEntity calibrationWaterRustCleanEntity = optional.get();


        entity.setCalibrationWaterRustCleanEntity(calibrationWaterRustCleanEntity);
        CalibrationWaterRustCleanChildEntity save = calibrationWaterRustCleanChildDao.save(entity);
        ////////////////////////////////
        // 动态计算
        calibrationWaterRustCleanEntity.getInner().add(entity);

        calc(calibrationWaterRustCleanEntity);

        // 查询父，进行计算
        calibrationWaterRustCleanDao.save(calibrationWaterRustCleanEntity);

//            calibrationWaterRustCleanDao.save(calibrationWaterRustCleanEntity);
        return AjaxResult.success(save);
    }

    @PutMapping("/child/{id}")
    public AjaxResult updateChild(@PathVariable("id") Long id, @RequestBody CalibrationWaterRustCleanChildEntity entity) {
        entity.setId(id);
        Optional<CalibrationWaterRustCleanEntity> optional = calibrationWaterRustCleanDao.findById(entity.getPid());
        if(!optional.isPresent()) {
            throw new ServiceException(MessageConstant.ERR_CALIBRATION_MISSION);
        }

        CalibrationWaterRustCleanEntity calibrationWaterRustCleanEntity = optional.get();

        entity.setCalibrationWaterRustCleanEntity(calibrationWaterRustCleanEntity);
        CalibrationWaterRustCleanChildEntity save = calibrationWaterRustCleanChildDao.save(entity);
        ///////////////////////////////////////
        // 动态计算
        calc(calibrationWaterRustCleanEntity);

        // 查询父，进行计算
        calibrationWaterRustCleanDao.save(calibrationWaterRustCleanEntity);

        save.setPid(entity.getPid());
        return AjaxResult.success(save);
    }

    @DeleteMapping("/child/{id}")
    public AjaxResult deleteChild(@PathVariable("id") Long id) {
        Optional<CalibrationWaterRustCleanChildEntity> childEntityOptional = calibrationWaterRustCleanChildDao.findById(id);
        if(!childEntityOptional.isPresent()) {
            throw new ServiceException(MessageConstant.ERR_CALIBRATION_MISSION);
        }

        CalibrationWaterRustCleanChildEntity childEntity = childEntityOptional.get();
        CalibrationWaterRustCleanEntity calibrationWaterCleanPointEntity = childEntity.getCalibrationWaterRustCleanEntity();
        calibrationWaterCleanPointEntity.getInner().remove(childEntity);
        // 动态计算
        calc(calibrationWaterCleanPointEntity);

        calibrationWaterRustCleanDao.save(calibrationWaterCleanPointEntity);

        calibrationWaterRustCleanChildDao.deleteById(id);

        //////////////////////
        return AjaxResult.success();
    }

    private CalibrationWaterRustCleanEntity calc(CalibrationWaterRustCleanEntity entity) {

        // power
        try {
            List<CalibrationWaterRustCleanChildEntity> inner = entity.getInner();
            double power = inner.stream()
                    .mapToDouble(CalibrationWaterRustCleanChildEntity::getPowerByHour)
                    .reduce(Double::sum)
                    .orElse(0.);
            entity.power = power;
        } catch (Exception e) {
            entity.power = 0.;
        }

        // powerByUnit
        try {
            entity.powerUnit = entity.power / entity.area;
        } catch (Exception e) {
            entity.powerUnit = 0.;
        }

        return entity;
    }

}
